// Package main 演示GORM更新操作，包括各种更新方法的使用
// 本示例详细展示了GORM提供的多种更新API及其适用场景
package main

import (
	"fmt"
	"gin-gorm/global"
	"gin-gorm/models"
	"time"

	"gorm.io/gorm"
)

// 各种更新方法的区别说明：
// 1. Save具有双重功能（创建或更新），而其他三个方法专门用于更新操作
// 2. Update和UpdateColumn可以处理零值，Save和Updates（使用结构体时）只更新非零值
// 3. UpdateColumn会绕过更新的Hook机制，适合需要跳过业务逻辑的场景
// 4. Updates方法根据参数类型（结构体或map）有不同的零值处理行为

// saveUpdate 演示Save方法的使用
// Save方法会根据结构体中的主键值决定是插入还是更新记录
// 如果主键存在则更新，不存在则插入
// Save会更新所有字段，包括零值字段
func saveUpdate() {
	var user models.UserModel
	user.ID = 2      // 设置主键ID，指定要更新的记录
	user.Name = "张三123" // 设置要更新的字段值
	user.CreatedAt = time.Now() // 更新创建时间
	global.DB.Save(&user) // 执行保存操作，会生成UPDATE语句
	fmt.Println(user) // 打印更新后的用户信息
}

// update 演示Update方法的使用
// Update方法用于更新单个字段
// 支持使用表达式进行字段计算
func update() {
	// 创建一个只包含ID的用户模型，用于指定要更新的记录
	var user = models.UserModel{ID: 2}
	// 直接更新age字段的值
	// global.DB.Model(&user).Update("age", 18) // 直接设置固定值
	// 使用表达式进行字段运算（年龄+1）
	// gorm.Expr用于构建SQL表达式，避免SQL注入
	global.DB.Model(&user).Update("age", gorm.Expr("age + ?", 1)) // 使用SQL表达式进行字段计算
	// UpdateColumn方法不触发任何钩子函数和时间戳自动更新
	// global.DB.Model(&user).UpdateColumn("age", 18) // 绕过钩子的单字段更新
	fmt.Println(user) // 打印更新后的用户信息
}

// updates 演示Updates方法的使用
// Updates方法用于同时更新多个字段
// 可接受结构体或map作为参数
func updates() {
	// 创建一个只包含ID的用户模型，用于指定要更新的记录
	var user = models.UserModel{ID: 2}
	// 使用结构体更新多个字段
	// 注意：使用结构体时，零值字段不会被更新
	global.DB.Model(&user).Updates(models.UserModel{
		Name: "zhangsan", // 非零值字段会被更新
		Age:  0, // 0是零值，不会被更新
	})
	fmt.Println(user) // 打印更新后的用户信息
}

// main 程序入口函数
// 初始化数据库连接并调用不同的更新方法进行演示
func main() {
	// 初始化数据库连接
	global.Connect()
	// saveUpdate() // 演示Save方法
	update() // 演示Update方法
	// updates() // 演示Updates方法
}
